#include "tribemgrdlg.h"
#include "ui_tribemgrdlg.h"
#include "../Biz/MsgBusParam/IMMessageParam.h"
#include "htmlformathelper.h"
#include "../Core/SimpleLogger.h"
#include "../Biz/WWCommonUtility.h"

#include <QTime>
#include <QUrl>
#include <QList>
#include <qlistwidget.h>
#include <QScrollBar>
#include <QDesktopServices>
#include <QSound>
#include <QFileDialog>

using namespace wwbiz;
using namespace core;
using namespace wwcommon;
using std::string;

static LoggerCategory g_log("TribeMgrDlg");

TribeMgrDlg::TribeMgrDlg(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::TribeMgrDlg)
{
    ui->setupUi(this);

    QObject::connect(this, SIGNAL(receiveTribeMsgs(MsgBusParam)), SLOT(OnReceiveTribeMsgs(MsgBusParam)));
    QObject::connect(this, SIGNAL(receiveAllTribeInfoReady(MsgBusParam)), SLOT(OnReceiveAllTribeInfoReady(MsgBusParam)));

    QObject::connect(this, SIGNAL(receiveTribeMemberInfoReady(MsgBusParam)), SLOT(OnReceiveTribeMemberInfoReady(MsgBusParam)));

    QObject::connect(ui->tribe_msg_sendbtn, SIGNAL(clicked()), SLOT(OnSendTribeMsgClicked()));
    QObject::connect(ui->received_tribe_msg_view, SIGNAL(anchorClicked(QUrl)), SLOT(OnAnchorClicked(QUrl)));
    QObject::connect(ui->tribe_member_list, SIGNAL(itemActivated(QListWidgetItem*)), SLOT(OnTribeMemberListItemClicked(QListWidgetItem*)));
    QObject::connect(ui->all_tribe_list, SIGNAL(itemActivated(QListWidgetItem*)), SLOT(OnTribeListItemClicked(QListWidgetItem*)));
    QObject::connect(ui->btn_clearmsgs, SIGNAL(clicked()), ui->received_tribe_msg_view, SLOT(clear()));

}
void TribeMgrDlg::InitMsgHandler()
{
    AddHandler("im.frontend.imreceiver.tribe.alltribeinfoready", &TribeMgrDlg::OnIMAllTribeInfoReady, 0);
    AddHandler("im.frontend.imreceiver.tribe.send.textmsg", &TribeMgrDlg::OnIMTribeTextMsg, 0);
    AddHandler("im.frontend.imreceiver.tribe.recv.notifymsg", &TribeMgrDlg::OnIMTribeTextMsg, 0);
    AddHandler("im.frontend.imreceiver.tribe.tribememberinfo.ready", &TribeMgrDlg::OnIMTribeMemberInfoReady, 0);
}

TribeMgrDlg::~TribeMgrDlg()
{
    delete ui;
}

void TribeMgrDlg::CleanDataOnLogout()
{
    m_alltribes.clear();
    m_alltribe_members.clear();

    ui->all_tribe_list->clear();
    ui->received_tribe_msg_view->clear();
    ui->tribe_member_list->clear();
    ui->tribe_msg_input->clear();
    ui->tribe_sendto_lable->clear();
}

void TribeMgrDlg::SetWWMainUniqueId(const std::string &uniqueid)
{
    m_wwmain_unique = uniqueid;
}

void TribeMgrDlg::OnAnchorClicked(QUrl url)
{
    QString str_url = url.toString();
    if(str_url.indexOf("#userid") == 0)
        emit tribeMemberClicked(url.toString().mid(QString("#userid").size()));
    else if(str_url.indexOf("#tribeid") == 0)
    {
        ui->tribe_sendto_lable->setText(str_url.mid(QString("#tribeid").size()));
    }
    else
    {
        QDesktopServices::openUrl(url);
    }
}

QString TribeMgrDlg::GetTribeMemberDispNameFromId(const PBTribeMemberInfo& meminfo)
{
    if(meminfo.name().empty() || meminfo.name() == meminfo.member_id())
    {
        return QString::fromStdString(meminfo.member_id());
    }
    else
    {
        return QString::fromStdString(meminfo.name() + "-" + meminfo.member_id());
    }
}

QString TribeMgrDlg::GetTribeMemberDispNameFromId(const PBTribeMemberInfoVec& memvec, const std::string &memberid)
{
    google::protobuf::RepeatedPtrField<PBTribeMemberInfo>::const_iterator memit = memvec.tribe_member().begin();
    while(memit != memvec.tribe_member().end())
    {
        if(memit->member_id() == memberid)
        {
            return GetTribeMemberDispNameFromId(*memit);
        }
        ++memit;
    }
    return QString::fromStdString(memberid);
}
// 如果有群名片则显示群名片-用户id,如果没用则显示用户id
QString TribeMgrDlg::GetTribeMemberDispNameFromId(const std::string& tribeid, const std::string &memberid)
{
    std::map<string, PBTribeMemberInfoVec>::const_iterator cit = m_alltribe_members.find(tribeid);
    if(cit == m_alltribe_members.end())
        return QString::fromStdString(memberid);
    return GetTribeMemberDispNameFromId(cit->second, memberid);
}

void TribeMgrDlg::OnSendTribeMsgClicked()
{
    IMTextMessage msg;

    QString sendto_tribe = ui->tribe_sendto_lable->text().trimmed();
    int idpos = sendto_tribe.lastIndexOf("-");
    if(idpos == -1)
        return;
    std::string tribe_id = sendto_tribe.mid(idpos + 1).toStdString();
    std::string scontent = ui->tribe_msg_input->toPlainText().toStdString();
    if(tribe_id.empty() || scontent.empty())
        return;
    msg.id_ = tribe_id;
    msg.message_ = scontent;

    NetMsgBus::NetMsgBusSendMsg(m_wwmain_unique, "im.frontend.dosendtribemsg.req", CustomType2Param(msg) , SendDirectToClient);
    ui->tribe_msg_input->clear();
    ui->tribe_msg_input->setFocus();
}

void TribeMgrDlg::OnTribeListItemClicked(QListWidgetItem* pitem)
{
    std::string tribeid = pitem->data(Qt::UserRole).toString().toStdString();
    TribeInfoContainerT::const_iterator cit = m_alltribes.find(tribeid);
    if(cit == m_alltribes.end())
    {
        return;
    }
    FillTribeMemberInfo(m_alltribe_members[tribeid]);
    ui->tribe_sendto_lable->setText(pitem->text());
}
void TribeMgrDlg::OnTribeMemberListItemClicked(QListWidgetItem* pitem)
{
    QString memberid = pitem->data(Qt::UserRole).toString();
    emit tribeMemberClicked(memberid);
}

void TribeMgrDlg::OnTribeImageNotify(MsgBusParam param)
{
    int current_pos = ui->received_tribe_msg_view->verticalScrollBar()->value();

    ui->received_tribe_msg_view->moveCursor(QTextCursor::End);
    ui->received_tribe_msg_view->insertHtml("&nbsp;");
    ui->received_tribe_msg_view->moveCursor(QTextCursor::End);
    ui->received_tribe_msg_view->verticalScrollBar()->setValue(current_pos);
}

void TribeMgrDlg::OnReceiveTribeMsgs(MsgBusParam param)
{
//    if(isMinimized())
//    {
//        showMinimized();
//    }
//    else
//    {
//        show();
//    }

    IMTextMessageVector msgvec;
    Param2CustomType(param, msgvec);
    QString htmlStr;
    for(size_t i = 0; i < msgvec.size(); i++)
    {
        const IMTextMessage& msg = msgvec[i];
        if(msg.type_ != 0x01)
        {
            g_log.Log(lv_debug, "got unspupported tribe msg.");
            continue;
        }
        QString timestr = HtmlFormatHelper::FormatTime(msg.time_);

        if(m_alltribes.find(msg.id_) == m_alltribes.end())
        {
            g_log.Log(lv_debug, "got tribe msg not founded in my tribe list.%s, %s", msg.id_.c_str(),
                      msg.message_.c_str());
            assert(0);
            continue;
        }
        QString tribedispname = HtmlFormatHelper::FormatTribeId(m_alltribes[msg.id_].tribe_name, msg.id_);
        // append message to message viewer
        if(msg.bsend_)
        {
            QSound::play("resources/newmsg.wav");
            htmlStr += QString("<br/>%1 said in %2: %3 <br/> %4 %5")
                    .arg(HtmlFormatHelper::FormatTribeMemberId(GetTribeMemberDispNameFromId(msg.id_, msg.fromuid_)))
                    .arg(tribedispname)
                    .arg(timestr)
                    .arg(HtmlFormatHelper::FormatMessageContent(msg.text_))
                    .arg(HtmlFormatHelper::FormatAllPicturesToHtml(msg.message_));
        }
        else
        {
            htmlStr += QString("<br/>I said in %1 : %2 <br/> %3 %4")
                    .arg(tribedispname)
                    .arg(timestr)
                    .arg(HtmlFormatHelper::FormatMessageContent(msg.text_))
                    .arg(HtmlFormatHelper::FormatAllPicturesToHtml(msg.message_));
        }
    }

    if(htmlStr.size() > 0)
    {
        emit newactivity();

        int current_pos = ui->received_tribe_msg_view->verticalScrollBar()->value();
        int oldmax = ui->received_tribe_msg_view->verticalScrollBar()->maximum();
        ui->received_tribe_msg_view->moveCursor(QTextCursor::End);
        ui->received_tribe_msg_view->insertHtml(htmlStr);
        ui->received_tribe_msg_view->moveCursor(QTextCursor::End);
        if(current_pos >= oldmax)
        {

            ui->received_tribe_msg_view->verticalScrollBar()->setValue(ui->received_tribe_msg_view->verticalScrollBar()->maximum());
        }
        else
        {
            ui->received_tribe_msg_view->verticalScrollBar()->setValue(current_pos);
        }

    }
}

void TribeMgrDlg::OnReceiveAllTribeInfoReady(MsgBusParam param)
{
    //show();
    //std::string testresult;
    //Param2CustomType(param, testresult);
    Param2CustomType(param, m_alltribes);
    //g_log.Log(lv_debug, "receive all tribe info ready. tribe num:%zu, data:%s", m_alltribes.size(), testresult.c_str());
    // init tribe list
    TribeInfoContainerT::iterator it = m_alltribes.begin();
    ui->all_tribe_list->clear();
    while(it != m_alltribes.end())
    {
        QListWidgetItem *item = new QListWidgetItem(QString::fromStdString(it->second.tribe_name) + "-" + QString::fromStdString(it->second.tribe_id));
        item->setData(Qt::UserRole, QString::fromStdString(it->second.tribe_id));
        ui->all_tribe_list->addItem(item);
        ++it;
    }
}

void TribeMgrDlg::FillTribeMemberInfo(wwbiz::PBTribeMemberInfoVec &memvec)
{
    google::protobuf::RepeatedPtrField<PBTribeMemberInfo>::const_iterator it = memvec.tribe_member().begin();
    ui->tribe_member_list->clear();
    while(it != memvec.tribe_member().end())
    {
        QListWidgetItem *item = new QListWidgetItem(GetTribeMemberDispNameFromId(*it));
        item->setData(Qt::UserRole, QString::fromStdString(it->member_id()));
        ui->tribe_member_list->addItem(item);
        ++it;
    }
}

void TribeMgrDlg::OnReceiveTribeMemberInfoReady(MsgBusParam param)
{
    PBTribeMemberInfoVec memvec;
    Param2PBType(param, memvec);
//    core::XParam memparam;
//    Param2CustomType(param, memparam);
    std::string tribeid;
    tribeid = memvec.tribe_id();
//    memparam.get_Str("tribeid", tribeid);
//    core::XParam memvecparam;
//    TribeMemberInfoVector memvec;
//    memparam.get_XParam("tribemembervec", memvecparam);
//    TribeMemberInfo::XParamToVectorType(memvecparam, memvec);
    //
    m_alltribe_members[tribeid] = memvec;
    QListWidgetItem *pitem = ui->all_tribe_list->currentItem();
    if(pitem && pitem->data(Qt::UserRole).toString() == QString::fromStdString(tribeid))
    {
        FillTribeMemberInfo(memvec);
    }
}

bool TribeMgrDlg::OnIMTribeTextMsg(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    emit receiveTribeMsgs(param);
    return true;
}

bool TribeMgrDlg::OnIMAllTribeInfoReady(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    emit receiveAllTribeInfoReady(param);
    return true;
}

bool TribeMgrDlg::OnIMTribeMemberInfoReady(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    emit receiveTribeMemberInfoReady(param);
    return true;
}

void TribeMgrDlg::on_btnHistory_clicked()
{
    emit openTribeHistory();
}

void TribeMgrDlg::on_btnSendPic_clicked()
{
    core::XParam xp;
    IMTextMessage msg;

    QString sendto_tribe = ui->tribe_sendto_lable->text().trimmed();
    int idpos = sendto_tribe.lastIndexOf("-");
    if(idpos == -1)
        return;
    std::string tribe_id = sendto_tribe.mid(idpos + 1).toStdString();
    if(tribe_id.empty())
        return;
    QStringList savedpathlist = QFileDialog::getOpenFileNames(this, "select picture(s) to send", "", "Images(*.png *.jpg *.jpeg *.bmp *.gif)");
    if(savedpathlist.size() < 1)
        return;
    else if(savedpathlist.size() > 5)
    {
        printf("5 pictures at most once.\n");
        return;
    }
    QStringList::iterator it = savedpathlist.begin();
    while(it != savedpathlist.end())
    {
        xp.put_Str(std::string("uid"), tribe_id);
        xp.put_Str(std::string("filename"), (*it).toStdString());
        // 0x01 stand for tribe image.
        xp.put_Int(std::string("filetype"), 0x01);
        NetMsgBus::NetMsgBusSendMsg(m_wwmain_unique, "im.frontend.filetransfer.offlinefile.dosendfile.req", CustomType2Param(xp), SendDirectToClient);
        ++it;
    }
    ui->tribe_msg_input->setFocus();
}
